#ifndef MOPARSE_H
#define MOPARSE_H

#include <string>
#include <vector>
#include <memory>
#include <set>
#include <map>
#include "modb.pb.h"

/**
 * @brief Verilog模块解析器类
 * 
 * 该类提供解析Verilog文件并生成.modb格式文件的功能
 */
class VerilogParser {
public:
    VerilogParser();
    ~VerilogParser();

    /**
     * @brief 解析单个Verilog文件
     * @param verilogFile Verilog文件路径
     * @param moduleName 指定要解析的模块名（可选）
     * @return 解析成功返回true，否则返回false
     */
    bool parseVerilogFile(const std::string& verilogFile, const std::string& moduleName = "");

    /**
     * @brief 解析Verilog文件列表
     * @param fileList 包含Verilog文件路径的列表文件
     * @param moduleName 指定要解析的模块名（可选）
     * @return 解析成功返回true，否则返回false
     */
    bool parseVerilogFileList(const std::string& fileList, const std::string& moduleName = "");
    
    /**
     * @brief 递归解析Verilog文件列表（支持-f嵌套）
     * @param fileList 包含Verilog文件路径的列表文件
     * @param moduleName 指定要解析的模块名（可选）
     * @param processedFiles 已处理文件集合（防止循环引用）
     * @return 解析成功返回true，否则返回false
     */
    bool parseVerilogFileListRecursive(const std::string& fileList, const std::string& moduleName, std::set<std::string>& processedFiles);

    /**
     * @brief 保存解析结果到.modb文件
     * @param outputFile 输出的.modb文件路径
     * @return 保存成功返回true，否则返回false
     */
    bool saveToModb(const std::string& outputFile);

    /**
     * @brief 从现有.modb文件加载数据
     * @param modbFile .modb文件路径
     * @return 加载成功返回true，否则返回false
     */
    bool loadFromModb(const std::string& modbFile);

    /**
     * @brief 合并解析结果到现有.modb文件
     * @param existingFile 现有的.modb文件路径
     * @return 合并成功返回true，否则返回false
     */
    bool mergeToExistingModb(const std::string& existingFile);

    /**
     * @brief 显示.modb文件中的模块信息
     * @param modbFile .modb文件路径
     * @param moduleName 指定模块名（可选）
     * @param verbose 是否显示详细信息
     */
    void showModuleInfo(const std::string& modbFile, const std::string& moduleName = "", bool verbose = false);

    /**
     * @brief 从.modb文件中删除指定模块
     * @param modbFile .modb文件路径
     * @param moduleName 要删除的模块名
     * @return 删除成功返回true，否则返回false
     */
    bool deleteModule(const std::string& modbFile, const std::string& moduleName);

    /**
     * @brief 反向生成Verilog代码
     * @param modbFile .modb文件路径
     * @param moduleName 模块名
     * @param outputFile 输出Verilog文件路径
     * @param mode 生成模式：e(空壳), es(空壳+stub), a(完整), i(实例)
     * @return 生成成功返回true，否则返回false
     */
    bool generateVerilog(const std::string& modbFile, const std::string& moduleName, 
                        const std::string& outputFile, const std::string& mode);
    
    /**
     * @brief 比较两个.modb文件中的模块
     * @param modbFile1 第一个.modb文件路径
     * @param moduleName1 第一个模块名
     * @param modbFile2 第二个.modb文件路径
     * @param moduleName2 第二个模块名
     */
    void compareModules(const std::string& modbFile1, const std::string& moduleName1, 
                       const std::string& modbFile2, const std::string& moduleName2);
    
    /**
     * @brief 显示模块的连接关系（顶层到子模块）
     * @param modbFile .modb文件路径
     * @param moduleName 模块名
     * @param submodule 指定的子模块名（可选）
     */
    void showConnectionsTop2Sub(const std::string& modbFile, const std::string& moduleName, 
                               const std::string& submodule = "");
    
    /**
     * @brief 显示两个子模块间的连接关系
     * @param modbFile .modb文件路径
     * @param moduleName 模块名
     * @param submoduleA 第一个子模块名
     * @param submoduleB 第二个子模块名
     */
    void showConnectionsSub2Sub(const std::string& modbFile, const std::string& moduleName, 
                               const std::string& submoduleA, const std::string& submoduleB);
    
    /**
     * @brief 导出模块连接关系为DOT格式（用于Graphviz）
     * @param modbFile .modb文件路径
     * @param moduleName 模块名
     * @param outputFile 输出DOT文件路径
     * @param submodule 指定的子模块名（可选，为空则显示所有连接）
     * @return 导出成功返回true，否则返回false
     */
    bool exportConnectionsToDot(const std::string& modbFile, const std::string& moduleName, 
                               const std::string& outputFile, const std::string& submodule = "");
    
    /**
     * @brief 显示模块的例化层次关系（树形结构）
     * @param modbFile .modb文件路径
     * @param moduleName 模块名
     */
    void showHierarchy(const std::string& modbFile, const std::string& moduleName);

    /**
     * @brief 获取解析的模块数据库
     * @return 模块数据库引用
     */
    const modb::ModbDatabase& getDatabase() const { return database_; }

private:
    modb::ModbDatabase database_;
    
    /**
     * @brief 解析模块定义
     * @param content Verilog文件内容
     * @param moduleName 模块名
     * @return 解析的模块对象
     */
    std::unique_ptr<modb::Module> parseModule(const std::string& content, const std::string& moduleName);
    
    /**
     * @brief 仅解析模块定义（不解析宏定义）
     * @param content Verilog文件内容
     * @param moduleName 模块名
     * @return 解析的模块对象
     */
    std::unique_ptr<modb::Module> parseModuleOnly(const std::string& content, const std::string& moduleName);
    
    /**
     * @brief 解析参数列表
     * @param content 模块内容
     * @param module 模块对象
     */
    void parseParameters(const std::string& content, modb::Module* module);
    
    /**
     * @brief 解析端口列表
     * @param content 模块内容
     * @param module 模块对象
     */
    void parsePorts(const std::string& content, modb::Module* module);
    
    /**
     * @brief 解析线网列表
     * @param content 模块内容
     * @param module 模块对象
     */
    void parseWires(const std::string& content, modb::Module* module);
    
    /**
     * @brief 解析实例列表
     * @param content 模块内容
     * @param module 模块对象
     */
    void parseInstances(const std::string& content, modb::Module* module);
    
    /**
     * @brief 解析端口连接信息
     * @param connections 端口连接字符串
     * @param instanceName 实例名
     * @param module 模块对象
     */
    void parsePortConnections(const std::string& connections, const std::string& instanceName, modb::Module* module);
    
    /**
     * @brief 为顶层端口添加连接信息
     * @param module 模块对象
     */
    void addTopPortConnections(modb::Module* module);
    
    /**
     * @brief 解析宏定义
     * @param content Verilog文件内容
     */
    void parseMacros(const std::string& content);
    
    /**
     * @brief 读取文件内容
     * @param filename 文件路径
     * @return 文件内容字符串
     */
    std::string readFile(const std::string& filename);
    
    /**
     * @brief 移除注释
     * @param content Verilog代码内容
     * @return 移除注释后的内容
     */
    std::string removeComments(const std::string& content);
    
    /**
     * @brief 查找模块在数据库中的索引
     * @param moduleName 模块名
     * @return 模块索引，未找到返回-1
     */
    int findModuleIndex(const std::string& moduleName);
    
    /**
     * @brief 生成空壳模块代码
     * @param module 模块对象
     * @param withStub 是否为输出端口添加assign 0
     * @return 生成的Verilog代码
     */
    std::string generateEmptyModule(const modb::Module& module, bool withStub = false);
    
    /**
     * @brief 生成模块实例代码
     * @param module 模块对象
     * @param instanceName 实例名（可选）
     * @return 生成的实例代码
     */
    std::string generateInstance(const modb::Module& module, const std::string& instanceName = "");
    
    /**
     * @brief 判断是否为注释行或编译器指令行
     * @param line 文件行内容
     * @return 如果是注释或指令返回true
     */
    bool isCommentOrDirective(const std::string& line);
    
    /**
     * @brief 判断是否为VCS编译器指令
     * @param line 文件行内容
     * @return 如果是VCS指令返回true
     */
    bool isVCSDirective(const std::string& line);
    
    /**
     * @brief 处理VCS编译器指令
     * @param line VCS指令行
     * @param moduleName 指定模块名
     * @param processedFiles 已处理文件集合
     * @return 处理成功返回true
     */
    bool processVCSDirective(const std::string& line, const std::string& moduleName, std::set<std::string>& processedFiles);

    /**
     * @brief 解析环境变量
     * @param path 包含环境变量的路径
     * @return 解析后的路径
     */
    std::string resolveEnvironmentVariables(const std::string& path);

};

/**
 * @brief 命令行参数处理和主程序入口相关函数
 */
namespace moparse {
    /**
     * @brief 解析命令行参数并执行相应操作
     * @param argc 参数个数
     * @param argv 参数数组
     * @return 执行成功返回0，否则返回错误代码
     */
    int main(int argc, char* argv[]);
    
    /**
     * @brief 显示帮助信息
     */
    void showHelp();
    
    /**
     * @brief 显示版本信息
     */
    void showVersion();
}

#endif // MOPARSE_H